package com.plian.system.service.im.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.excel.write.metadata.fill.FillWrapper;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.fasterxml.jackson.core.type.TypeReference;
import com.plian.Tools.*;
import com.plian.Tools.pagedata.PageData;
import com.plian.system.bean.im.BaseInvestmentDebtImportExcelBean;
import com.plian.system.common.status.CustomCode;
import com.plian.system.config.RedisUtils;
import com.plian.system.constant.sys.FormStatusConstant;
import com.plian.system.constant.sys.FormTypeConstant;
import com.plian.system.dao.pm.property.PropertyBasicsDao;
import com.plian.system.dao.sys.orgzation.OrgzationDao;
import com.plian.system.dto.im.BaseInvestmentDebtDTO;
import com.plian.system.entity.im.BaseInvestmentDebt;
import com.plian.system.entity.im.InvestmentDebt;
import com.plian.system.excel.ImportExcelUtil;
import com.plian.system.excel.ImportResult;
import com.plian.system.mapper.im.BaseInvestmentDebtMapper;
import com.plian.system.model.CommonCode;
import com.plian.system.model.ListResult;
import com.plian.system.model.ObjResult;
import com.plian.system.model.R;
import com.plian.system.mybatis.base.BaseFlowService;
import com.plian.system.mybatis.base.BaseServiceImpl;
import com.plian.system.mybatis.search.SearchEntity;
import com.plian.system.mybatis.search.SearchParamEntiy;
import com.plian.system.mybatis.support.Condition;
import com.plian.system.mybatis.support.Query;
import com.plian.system.service.hr.dept.IDeptService;
import com.plian.system.service.im.IBaseInvestmentDebtService;
import com.plian.system.service.im.IInvestmentDebtService;
import com.plian.system.service.sys.code.IFormCodeService;
import com.plian.system.service.sys.orgzation.IOrgService;
import com.plian.system.service.sys.orgzation.OrgzationService;
import com.plian.system.service.sys.user.ISysUserService;
import com.plian.system.service.wf.FormWorkflowService;
import com.plian.system.service.yth.IDebtStructureService;
import com.plian.system.vo.im.BaseInvestmentDebtVO;
import com.plian.system.vo.im.InvestmentDebtSummaryVO;
import com.plian.system.vo.im.InvestmentDebtTreeVO;
import com.plian.system.vo.im.InvestmentDebtVO;
import com.plian.system.wrapper.im.BaseInvestmentDebtWrapper;
import com.plian.system.wrapper.im.InvestmentDebtWrapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

import static com.plian.system.constant.sys.FormStatusConstant.UNREVIEWED;

/**
 * 服务实现类
 *
 * @author
 * @since 2019-09-27
 */
@Slf4j
@Service
@AllArgsConstructor
public class BaseInvestmentDebtServiceImpl extends BaseServiceImpl<BaseInvestmentDebtMapper, BaseInvestmentDebt> implements IBaseInvestmentDebtService, BaseFlowService {

    private FormWorkflowService formWorkflowService;

    private IInvestmentDebtService investmentDebtService;

    private Environment environment;

    private IFormCodeService formCodeService;

    private OrgzationService orgzationService;

    private OrgzationDao orgzationDao;

//    private IInvestmentDebtInfoService investmentDebtInfoService; TODO DEL

    private PropertyBasicsDao propertyBasicsDao;

    private RedisUtils redisUtils;

    private InvestmentDebtWrapper investmentDebtWrapper;

    private BaseInvestmentDebtWrapper baseInvestmentDebtWrapper;

    @Autowired
    private IDebtStructureService debtStructureService;

    private ISysUserService userService;

    private IOrgService orgService;

    private IDeptService deptService;


    private static final Map<String, String> fileNameMap = new HashMap<>();

    @Override
    public boolean saveOrUpdate(BaseInvestmentDebt baseInvestmentDebt) {

        if (!Optional.ofNullable(baseInvestmentDebt.getStatus()).isPresent()) {
            baseInvestmentDebt.setStatus(FormStatusConstant.UNREVIEWED);
        }
        if (!Optional.ofNullable(baseInvestmentDebt.getId()).isPresent()) {
            baseInvestmentDebt.setCode(formCodeService.getCode(FormTypeConstant.IM_BASE_INVESTMENT_DEBT_FORM));
            baseInvestmentDebt.setFormType(String.valueOf(FormTypeConstant.IM_BASE_INVESTMENT_DEBT_FORM));
        }
        List<InvestmentDebtVO> summaryList = baseInvestmentDebt.getSummaryList();
        if (CollectionUtil.isNotEmpty(summaryList)) {
            baseInvestmentDebt.setSummaryJson(JSON.toJSONString(summaryList));
        }

        return super.saveOrUpdate(baseInvestmentDebt);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public boolean deleteLogic(List<Long> ids) {
        for (Long id : ids) {
            BaseInvestmentDebt baseInvestmentDebt = getById(id);
            if (baseInvestmentDebt == null) {
                return false;
            } else if (baseInvestmentDebt.getStatus() != null &&
                    (baseInvestmentDebt.getStatus() != FormStatusConstant.STASH && baseInvestmentDebt.getStatus() != FormStatusConstant.UNREVIEWED)) {
                return false;
            }
            formWorkflowService.deleteProcessInstance(String.valueOf(id));
        }

        boolean result = super.deleteLogic(ids);
        if (result) {
            investmentDebtService.deleteByParentId(ids);
        }
        return result;
    }

    @Override
    public HashMap<String, Object> commit(String id) {
        handleStatus(Long.valueOf(id), FormStatusConstant.FLOW);

        //将需要提交的流程变量返回，用于工作流侧
        return new HashMap<String, Object>();
    }

    @Override
    public Boolean finish(String id) {
        return handleStatus(Long.valueOf(id), FormStatusConstant.FINISH);
    }

    @Override
    public Boolean reject(String id, int formState, String comment) {
        return handleStatus(Long.valueOf(id), formState);
    }

    @Override
    public String checkMonth(BaseInvestmentDebt baseInvestmentDebt) {
        LambdaQueryWrapper<BaseInvestmentDebt> queryWrapper = new LambdaQueryWrapper<>();
        if (!Optional.ofNullable(baseInvestmentDebt.getFilingMonth()).isPresent()) {
            return "填报时间为空";
        }
        if (!Optional.ofNullable(baseInvestmentDebt.getFilingUnitId()).isPresent()) {
            return "填报单位为空";
        }
        queryWrapper.eq(BaseInvestmentDebt::getFilingUnitId, baseInvestmentDebt.getFilingUnitId());
        queryWrapper.eq(BaseInvestmentDebt::getFilingMonth, baseInvestmentDebt.getFilingMonth());
        queryWrapper.eq(BaseInvestmentDebt::getType, baseInvestmentDebt.getType());
        BaseInvestmentDebt one = getOne(queryWrapper);
        if (!Optional.ofNullable(one).isPresent()) {
            return null;
        }
        if (one.getId().equals(baseInvestmentDebt.getId())) {
            return null;
        }
        return "该月份已填报";
    }


    /**
     * 统一处理状态机事件方法
     *
     * @param id           主键
     * @param updateStatus 更新状态
     * @return boolean
     */
    private Boolean handleStatus(Long id, int updateStatus) {
        try {
            BaseInvestmentDebt baseInvestmentDebt = getById(id);
            /**
             * 设置审批人和审批时间
             */
            if (updateStatus == FormStatusConstant.FINISH) {
                baseInvestmentDebt.setApprovedUser(TokenUtil.getTokenUserId());
                Date now = DateUtil.now();
                baseInvestmentDebt.setApprovedTime(now);
            }
            baseInvestmentDebt.setStatus(updateStatus);
            updateById(baseInvestmentDebt);
            return true;
        } catch (Exception e) {
            log.error(ExceptionUtils.getFullStackTrace(e));
            return false;
        }
    }


    @Override
    public List<PageData> findByIds(List<String> formIds) {
        LambdaQueryWrapper<BaseInvestmentDebt> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(BaseInvestmentDebt::getId, Func.toLongList(StringUtils.join(formIds, StringPool.COMMA)));
        List<BaseInvestmentDebt> baseInvestmentDebts = list(queryWrapper);
        List<BaseInvestmentDebtVO> baseInvestmentDebtVOS = baseInvestmentDebtWrapper.entityToVO(baseInvestmentDebts);
        List<PageData> pageDataList = new ArrayList<>();
        try {
            if (CollectionUtil.isNotEmpty(baseInvestmentDebtVOS)) {
                for (BaseInvestmentDebtVO vo : baseInvestmentDebtVOS) {
                    PageData pd = new PageData();
                    pd.put("id", vo.getId());
                    pd.put("UNITNAME", vo.getFilingUnitName());
                    pd.put("APPLICANTNAME", vo.getCreateUserName());
                    pd.put("applicantId", vo.getCreateUser());
                    pd.put("applyOrganizationId", vo.getFilingUnitId());
                    pd.put("formType", FormTypeConstant.IM_BASE_INVESTMENT_DEBT_FORM);
                    pd.put("orgName", vo.getFilingUnitName());
                    pageDataList.add(pd);
                }
            }

            return pageDataList;
        } catch (Exception e) {
            log.error(ExceptionUtils.getFullStackTrace(e));
        }
        return pageDataList;
    }

    @Override
    public List<Integer> getFormType() {
        return Collections.singletonList(FormTypeConstant.IM_BASE_INVESTMENT_DEBT_FORM);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public boolean submit(BaseInvestmentDebt baseInvestmentDebt) {
        boolean result = saveOrUpdate(baseInvestmentDebt);
        if (result) {

            List<InvestmentDebt> investmentDebts = baseInvestmentDebt.getInvestmentDebts();
            if (CollectionUtil.isNotEmpty(investmentDebts)) {
                for (InvestmentDebt investmentDebt : investmentDebts) {
                    if (investmentDebt.getId() != null &&
                            Optional.ofNullable(investmentDebt.getIsDeleted()).isPresent() && investmentDebt.getIsDeleted().intValue() == 1) {
                        investmentDebtService.removeById(investmentDebt.getId());
                    } else {
                        investmentDebt.setBaseInvestmentDebtId(baseInvestmentDebt.getId());
                        investmentDebtService.saveOrUpdate(investmentDebt);
                    }
                }
            }
        }

        return result;
    }

    @Override
    public R<BaseInvestmentDebtVO> getDetailObj(BaseInvestmentDebtVO baseInvestmentDebtVO) {
        if (!Optional.ofNullable(baseInvestmentDebtVO).isPresent()) {
            return new R(CommonCode.FAIL);
        }
        if (StringUtil.isNotBlank(baseInvestmentDebtVO.getSummaryJson())) {
            baseInvestmentDebtVO.setSummaryList(JSON.parseObject(baseInvestmentDebtVO.getSummaryJson(),
                    new TypeReference<List<InvestmentDebtVO>>() {
                    }.getType()));
        }
        baseInvestmentDebtVO.setInvestmentDebtVOS(investmentDebtWrapper.entityToVO(investmentDebtService.list(new LambdaQueryWrapper<InvestmentDebt>()
                .eq(InvestmentDebt::getBaseInvestmentDebtId, baseInvestmentDebtVO.getId()))));
        return R.data(baseInvestmentDebtVO);
    }

    @Override
    public void goBackToStash(String formId) {
        handleStatus(Long.valueOf(formId), UNREVIEWED);
    }

    @Override
    public String export(Long baseInvestmentDebtId) {
        String key = baseInvestmentDebtId + StringPool.DASH + UUID.randomUUID().toString().replace(StringPool.DASH, "");
        String fileName = key + ".xlsx";
        String exportPath = environment.getProperty("excel.path");

        /**
         * 导出路径不存在则创建
         */
        File file = new File(exportPath);
        if (!file.exists()) {
            file.mkdirs();
        }
        InputStream inputStream = this.getClass().getResourceAsStream("/exceldemo/investmentDept.xlsx");
        ExcelWriter excelWriter = EasyExcel.write(exportPath + fileName).withTemplate(inputStream).build();

        // 这里注意 入参用了forceNewRow 代表在写入list的时候不管list下面有没有空行 都会创建一行，然后下面的数据往后移动。默认 是false，会直接使用下一行，如果没有则创建。
        // forceNewRow 如果设置了true,有个缺点 就是他会把所有的数据都放到内存了，所以慎用
        // 简单的说 如果你的模板有list,且list不是最后一行，下面还有数据需要填充 就必须设置 forceNewRow=true 但是这个就会把所有数据放到内存 会很耗内存

        FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();

        // 表一
        WriteSheet writeSheet = EasyExcel.writerSheet(0).build();
        List<InvestmentDebt> investmentDebts = investmentDebtService.list(new QueryWrapper<InvestmentDebt>()
                .eq("base_investment_debt_id", baseInvestmentDebtId));
        investmentDebtService.write(investmentDebts, excelWriter, writeSheet, fillConfig);

        BaseInvestmentDebtVO baseInvestmentDebtVO = baseInvestmentDebtWrapper.entityToVO(getById(baseInvestmentDebtId));
        // 其他参数可以使用Map封装
        Map<String, Object> otherMap = new HashMap<>(16);
        otherMap.put("filingUnitName", baseInvestmentDebtVO.getFilingUnitName());
        otherMap.put("deptName", baseInvestmentDebtVO.getDeptName());
//		otherMap.put("filingMonth", baseInvestmentDebtVO.getFilingMonth());
        otherMap.put("filingYear", baseInvestmentDebtVO.getFilingMonth().split(StringPool.DASH)[0]);
        otherMap.put("filingMonth", Integer.parseInt(baseInvestmentDebtVO.getFilingMonth().split(StringPool.DASH)[1]) < 10 ? baseInvestmentDebtVO.getFilingMonth().split(StringPool.DASH)[1].replace("0", "") + "月份" : baseInvestmentDebtVO.getFilingMonth().split(StringPool.DASH)[1] + "月份");


        excelWriter.fill(otherMap, writeSheet);
        excelWriter.finish();
        String excelName = baseInvestmentDebtVO.getFilingMonth() + "国有企业投资项目债务余额及结构情况表_" + baseInvestmentDebtVO.getFilingUnitName();
        fileNameMap.put(key, excelName);
        return key;
    }

    @Override
    public String exportImportFile(Long baseInvestmentDeptId) {
        String key = baseInvestmentDeptId + StringPool.DASH + UUID.randomUUID().toString().replace(StringPool.DASH, "");
        String fileName = key + ".xlsx";
        String exportPath = environment.getProperty("excel.path");

        /**
         * 导出路径不存在则创建
         */
        File file = new File(exportPath);
        if (!file.exists()) {
            file.mkdirs();
        }
        InputStream inputStream = this.getClass().getResourceAsStream("/exceldemo/baseInvestmentDebtExport.xlsx");
        ExcelWriter excelWriter = EasyExcel.write(exportPath + fileName).withTemplate(inputStream).build();

        // 这里注意 入参用了forceNewRow 代表在写入list的时候不管list下面有没有空行 都会创建一行，然后下面的数据往后移动。默认 是false，会直接使用下一行，如果没有则创建。
        // forceNewRow 如果设置了true,有个缺点 就是他会把所有的数据都放到内存了，所以慎用
        // 简单的说 如果你的模板有list,且list不是最后一行，下面还有数据需要填充 就必须设置 forceNewRow=true 但是这个就会把所有数据放到内存 会很耗内存

        FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
        // 表一
        WriteSheet baseWriteSheet = EasyExcel.writerSheet(0).build();
        BaseInvestmentDebtVO baseInvestmentDebtVO = baseInvestmentDebtWrapper.entityToVO(getById(baseInvestmentDeptId));
        // 其他参数可以使用Map封装
        Map<String, Object> baseMap = new HashMap<>(16);
        baseMap.put("filingUnitName", baseInvestmentDebtVO.getFilingUnitName());
        baseMap.put("deptName", baseInvestmentDebtVO.getDeptName());
        baseMap.put("filingMonth", baseInvestmentDebtVO.getFilingMonth());
        excelWriter.fill(baseMap, baseWriteSheet);

        // 表二
        WriteSheet investmentWriteSheet = EasyExcel.writerSheet(1).build();
        List<InvestmentDebt> investmentDebts = investmentDebtService.list(new LambdaQueryWrapper<InvestmentDebt>()
                .eq(InvestmentDebt::getBaseInvestmentDebtId, baseInvestmentDeptId));
        excelWriter.fill(new FillWrapper("investmentDebts", investmentDebtWrapper.entityToDto(investmentDebts)), fillConfig, investmentWriteSheet);
        excelWriter.finish();
        String excelName = baseInvestmentDebtVO.getFilingMonth() + StringPool.UNDERSCORE + baseInvestmentDebtVO.getFilingUnitName()
                + StringPool.UNDERSCORE + baseInvestmentDebtVO.getDeptName() + "_项目债务余额及结构";
        fileNameMap.put(key, excelName);
        return key;
    }

    @Override
    public void download(String key, HttpServletResponse response, OutputStream os) {
        if (!fileNameMap.containsKey(key)) {
            log.error("BaseInvestmentDebtServiceImpl 导出excel失败--------> key " + key);
            return;
        }
        String excelName = fileNameMap.get(key);
        String excelPath = environment.getProperty("excel.path") + StringPool.SLASH + key + ".xlsx";
        FileTools.exportExcel(excelPath, excelName, response);
        fileNameMap.remove(key);
    }

    @Override
    public R<BaseInvestmentDebtVO> getLastMonthObj(BaseInvestmentDebt baseInvestmentDebt) {
        String filingMonth = baseInvestmentDebt.getFilingMonth();
        Calendar c = Calendar.getInstance();
        c.setTime(DateUtil.parse(filingMonth, DateUtil.PATTERN_MONTH));
        c.add(Calendar.MONTH, -1);
        String lastMonth = DateUtil.format(c.getTime(), DateUtil.PATTERN_MONTH);
        PageData pd = new PageData();
        BaseInvestmentDebt last = getOne(new LambdaQueryWrapper<BaseInvestmentDebt>()
                .eq(BaseInvestmentDebt::getFilingUnitId, baseInvestmentDebt.getFilingUnitId())
                .eq(BaseInvestmentDebt::getType, 1)
                .eq(BaseInvestmentDebt::getFilingMonth, lastMonth));
        BaseInvestmentDebtVO baseInvestmentDebtVO = baseInvestmentDebtWrapper.entityToVO(last);
        if (Optional.ofNullable(last).isPresent()) {

            if (StringUtil.isNotBlank(last.getSummaryJson())) {
                baseInvestmentDebtVO.setSummaryList(JSON.parseObject(last.getSummaryJson(),
                        new TypeReference<List<InvestmentDebtVO>>() {
                        }.getType()));
            }
            baseInvestmentDebtVO.setInvestmentDebtVOS(investmentDebtWrapper.entityToVO(investmentDebtService.list(new LambdaQueryWrapper<InvestmentDebt>()
                    .eq(InvestmentDebt::getBaseInvestmentDebtId, last.getId()))));

        }
        return R.data(baseInvestmentDebtVO);
    }

    @Override
    public ObjResult tree(BaseInvestmentDebt baseInvestmentDebt) {
        String fillingMonth = baseInvestmentDebt.getFilingMonth();
        if (StringUtil.isBlank(fillingMonth)) {
            fillingMonth = DateUtil.format(DateUtil.now(), DateUtil.PATTERN_MONTH);
        }
        String filingUnitId = baseInvestmentDebt.getFilingUnitId();
        List<PageData> orgList = new ArrayList<>();
        if (StringUtil.isNotBlank(filingUnitId)) {
            orgList = orgzationService.orgTree(filingUnitId).getList();
        } else {
            orgList = orgzationService.getSubordinate().getList();
        }
        LambdaQueryWrapper<BaseInvestmentDebt> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BaseInvestmentDebt::getFilingMonth, fillingMonth);
        List<BaseInvestmentDebt> baseInvestmentDebts = list(queryWrapper);
//		List<PageData> orgList = orgzationService.getSubordinate().getList();
        if (CollectionUtil.isEmpty(orgList)) {
            return new ObjResult(CustomCode.builder().message("企业树初始化失败").code(1999).success(false).build());
        }
        Map<String, List<BaseInvestmentDebt>> oneMap = new HashMap<>();
        Map<String, List<BaseInvestmentDebt>> twoMap = new HashMap<>();

        if (CollectionUtil.isNotEmpty(baseInvestmentDebts)) {
            oneMap = baseInvestmentDebts.stream().filter(data -> data.getType() != null && data.getType() == 1)
                    .collect(Collectors.groupingBy(BaseInvestmentDebt::getFilingUnitId));
            twoMap = baseInvestmentDebts.stream().filter(data -> data.getType() != null && data.getType() == 2)
                    .collect(Collectors.groupingBy(BaseInvestmentDebt::getFilingUnitId));
        }

        List<InvestmentDebtTreeVO> tree = setTree(orgList, oneMap, twoMap);
        InvestmentDebtTreeVO result = new InvestmentDebtTreeVO();
        if (CollectionUtil.isNotEmpty(tree)) {
            result = tree.get(0);
        }
//        List<InvestmentDebtTreeVO> children = result.getChildren();
//        children.removeIf(investmentDebtTreeVO -> {
//            return investmentDebtTreeVO.getStatus()==5;
//        });

        ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
        PageData pd = new PageData();
        pd.put("tree", result);
        objResult.setPageData(pd);
        return objResult;
    }


    @Override
    public ListResult<PageData> treeList(Query query) {
        List<SearchEntity> entityList = query.getSearch();
        if (query.getAscs() == null && query.getDescs() == null) {
            query.setDescs("filing_month");
        }
        QueryWrapper<BaseInvestmentDebt> queryWrapper = SearchParamEntiy.getQueryWrapper(
                Condition.getQueryWrapper(new BaseInvestmentDebt()), entityList
        );
        queryWrapper.lambda().eq(BaseInvestmentDebt::getCreateCompanyId, TokenUtil.getTokenOrgId());

        if (isParent(TokenUtil.getTokenOrgId())) {
            queryWrapper.lambda().eq(BaseInvestmentDebt::getType, 2);
        } else {
            queryWrapper.lambda().eq(BaseInvestmentDebt::getType, 1);
        }

        IPage<BaseInvestmentDebt> pages = page(Condition.getPage(query), queryWrapper);
        List<BaseInvestmentDebtVO> baseInvestmentDebtVOS = baseInvestmentDebtWrapper.entityToVO(pages.getRecords());
        List<PageData> pageDataList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(baseInvestmentDebtVOS)) {
            for (BaseInvestmentDebtVO vo : baseInvestmentDebtVOS) {
                PageData pd = new PageData();
                pd.put("fillingUnitId", vo.getFilingUnitId());
                pd.put("fillingUnitName", vo.getFilingUnitName());
                pd.put("fillingMonth", vo.getFilingMonth());
                pd.put("baseInvestmentDebtId", vo.getId().toString());
                pd.put("deptName", vo.getDeptName());
                if (vo.getType() == 1) {
                    pd.put("typeName", "单户表");
                } else {
                    pd.put("typeName", "集团合并表");
                }
                pd.put("formType", FormTypeConstant.IM_BASE_INVESTMENT_DEBT_FORM);
                pd.put("type", vo.getType());
                pd.put("status", vo.getStatus());
                pageDataList.add(pd);
            }
        }
        ListResult<PageData> listResult = new ListResult<>(CommonCode.SUCCESS);
        listResult.setList(pageDataList);
        listResult.setTotal(Long.valueOf(pages.getTotal()).intValue());
        return listResult;
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public ObjResult addTree(BaseInvestmentDebt baseInvestmentDebt) {
        String fillingMonth = baseInvestmentDebt.getFilingMonth();
        if (StringUtil.isBlank(fillingMonth)) {
            return new ObjResult(CustomCode.builder().message("填报年月为空").code(1999).success(false).build());
        }
        String fillingUnitId = TokenUtil.getTokenOrgId();
        //单表数据
        BaseInvestmentDebt oneOldBase = getOne(new LambdaQueryWrapper<BaseInvestmentDebt>()
                .eq(BaseInvestmentDebt::getFilingMonth, fillingMonth)
                .eq(BaseInvestmentDebt::getFilingUnitId, fillingUnitId)
                .eq(BaseInvestmentDebt::getType, 1));
        boolean result = true;
        if (!Optional.ofNullable(oneOldBase).isPresent()) {
            List<InvestmentDebt> oneChildList = new ArrayList<>();
            BaseInvestmentDebt oneBase = BaseInvestmentDebt.builder().filingMonth(fillingMonth).filingUnitId(fillingUnitId).type(1).build();
            result = this.saveOrUpdate(oneBase);

            Calendar c = Calendar.getInstance();
            c.setTime(DateUtil.parse(fillingMonth, DateUtil.PATTERN_MONTH));
            c.add(Calendar.MONTH, -1);
            String lastMonth = DateUtil.format(c.getTime(), DateUtil.PATTERN_MONTH);
            BaseInvestmentDebt last = getOne(new LambdaQueryWrapper<BaseInvestmentDebt>()
                    .eq(BaseInvestmentDebt::getFilingUnitId, baseInvestmentDebt.getFilingUnitId())
                    .eq(BaseInvestmentDebt::getFilingMonth, lastMonth));
            if (Optional.ofNullable(last).isPresent()) {
                if (StringUtil.isNotBlank(last.getSummaryJson())) {
                    List summaryList = JSON.parseObject(last.getSummaryJson(), new TypeReference<List<InvestmentDebtVO>>() {
                    }.getType());
                    oneChildList.addAll(summaryList);
                }
                List<InvestmentDebtVO> investmentDebtVOS = investmentDebtWrapper.entityToVO(investmentDebtService.list(new LambdaQueryWrapper<InvestmentDebt>()
                        .eq(InvestmentDebt::getBaseInvestmentDebtId, last.getId())));
                oneChildList.addAll(investmentDebtVOS);
            }

            if (CollectionUtil.isNotEmpty(oneChildList)) {
                investmentDebtService.saveBatch(oneChildList);
            }
        }
        List<String> childIds = getChildIds(fillingUnitId);
        if (CollectionUtil.isNotEmpty(childIds)) {
            BaseInvestmentDebt twoOldBase = getOne(new LambdaQueryWrapper<BaseInvestmentDebt>()
                    .eq(BaseInvestmentDebt::getFilingMonth, fillingMonth)
                    .eq(BaseInvestmentDebt::getFilingUnitId, fillingUnitId)
                    .eq(BaseInvestmentDebt::getType, 2));
            if (!Optional.ofNullable(twoOldBase).isPresent()) {
                // 该企业有下级 创建合计数据
                BaseInvestmentDebt twoBase = BaseInvestmentDebt.builder().filingMonth(fillingMonth).filingUnitId(fillingUnitId).type(2).build();
                this.saveOrUpdate(twoBase);
            }
        }
        return result ? new ObjResult(CommonCode.SUCCESS) : new ObjResult(CommonCode.FAIL);
    }

    @Override
    public ObjResult childList(BaseInvestmentDebt baseInvestmentDebt) {
        String fillingMonth = baseInvestmentDebt.getFilingMonth();
        if (StringUtil.isBlank(fillingMonth)) {
            return new ObjResult(CustomCode.builder().message("填报年月为空").code(1999).success(false).build());
        }
        String fillingUnitId = baseInvestmentDebt.getFilingUnitId();
        if (StringUtil.isBlank(fillingUnitId)) {
            return new ObjResult(CustomCode.builder().message("填报单位为空").code(1999).success(false).build());
        }

        //本级单户表
        List<BaseInvestmentDebtVO> results = new ArrayList<>();
        LambdaQueryWrapper<BaseInvestmentDebt> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BaseInvestmentDebt::getFilingMonth, fillingMonth);
        queryWrapper.eq(BaseInvestmentDebt::getFilingUnitId, fillingUnitId);
        queryWrapper.eq(BaseInvestmentDebt::getType, 1);
        BaseInvestmentDebtVO baseVO = baseInvestmentDebtWrapper.entityToVO(getOne(queryWrapper));
        if (Optional.ofNullable(baseVO).isPresent()) {
            baseVO.setTypeName("单户表");
            results.add(baseVO);
        }

        //下级合计表和单户表 不包括孙子级
        List<PageData> childList = orgzationService.getChildrenByPId(fillingUnitId);
        if (CollectionUtil.isNotEmpty(childList)) {
            List<String> childIds = new ArrayList<>();
            Map<String, String> childOrgMap = new HashMap<>();
            for (PageData child : childList) {
                childIds.add((String) child.get("id"));
                childOrgMap.put((String) child.get("id"), (String) child.get("name"));
            }

            List<BaseInvestmentDebt> childBaseList = list(new LambdaQueryWrapper<BaseInvestmentDebt>()
                    .eq(BaseInvestmentDebt::getFilingMonth, fillingMonth).in(BaseInvestmentDebt::getFilingUnitId, childIds));
            if (CollectionUtil.isNotEmpty(childBaseList)) {

                // 剔除有合并表数据企业的单表数据
                Map<String, List<BaseInvestmentDebt>> baseInvestmentDebtMap = childBaseList.stream().collect(Collectors.groupingBy(BaseInvestmentDebt::getFilingUnitId));
                List<Long> delId = new ArrayList<>();
                baseInvestmentDebtMap.forEach((k, v) -> {
                    if (CollectionUtil.isNotEmpty(v) && v.size() > 1) {
                        for (BaseInvestmentDebt child : v) {
                            if (Optional.ofNullable(child.getType()).isPresent() && child.getType() == 1) {
                                delId.add(child.getId());
                            }
                        }
                    }
                });

                for (BaseInvestmentDebt childBase : childBaseList) {
                    if (!delId.contains(childBase.getId())) {
                        BaseInvestmentDebtVO baseInvestmentDebtVO = new BaseInvestmentDebtVO();
                        baseInvestmentDebtVO.setId(childBase.getId());
                        baseInvestmentDebtVO.setFilingUnitId(childBase.getFilingUnitId());
                        baseInvestmentDebtVO.setFilingUnitName(childOrgMap.get(childBase.getFilingUnitId()));
                        baseInvestmentDebtVO.setFilingMonth(childBase.getFilingMonth());
                        baseInvestmentDebtVO.setType(childBase.getType());
                        baseInvestmentDebtVO.setStatus(childBase.getStatus());
                        if (Optional.ofNullable(childBase.getType()).isPresent()) {
                            if (childBase.getType() == 1) {
                                baseInvestmentDebtVO.setTypeName("单户表");
                            } else if (childBase.getType() == 2) {
                                baseInvestmentDebtVO.setTypeName("集团合并表");
                            }
                        }
                        results.add(baseInvestmentDebtVO);
                    }
                }
            }
        }

        PageData pd = new PageData();
        pd.put("childList", results);
        ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
        objResult.setPageData(pd);
        return objResult;
    }

//    @Override TODO DEL
//    public ObjResult childSummary(BaseInvestmentDebt baseInvestmentDebt) {
//        List<Long> childIds = baseInvestmentDebt.getChildIds();
//        if (CollectionUtil.isEmpty(childIds)) {
//            return new ObjResult(CustomCode.builder().message("未勾选项目").code(1999).success(false).build());
//        }
//
//        ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
////		List<InvestmentDebtVO> investmentDebtVOS = investmentDebtMapper.summaryByBaseIds(childIds);
//        PageData pd = new PageData();
//        pd.put("childIds", childIds);
////		pd.put("summaryList", investmentDebtVOS);
//        List<InvestmentDebtVO> vos = investmentDebtWrapper.entityToVO(investmentDebtService
//                .list(new LambdaQueryWrapper<InvestmentDebt>().in(InvestmentDebt::getBaseInvestmentDebtId, childIds)));
//        for (InvestmentDebtVO vo : vos) {
//            vo.setId(null);
//            vo.setCreateUser(null);
//            vo.setCreateTime(null);
//            vo.setCreateCompanyId(null);
//            vo.setUpdateUser(null);
//            vo.setUpdateTime(null);
//        }
//        pd.put("investmentDebtVOS", vos);
//        objResult.setPageData(pd);
//
//        return objResult;
//    }

    @Override
    public void exportTemplateExcel(HttpServletResponse response, OutputStream os) {
        try {
            String fname = "债务余额与结构情况导入模板";
            os = response.getOutputStream();//取得输出流
            response.reset();//清空输出流
            //下面是对中文文件名的处理
            response.setCharacterEncoding("UTF-8");//设置相应内容的编码格式
            InputStream inputStream = this.getClass().getResourceAsStream("/exceldemo/baseInvestmentDebt.xlsx");
            fname = java.net.URLEncoder.encode(fname, "UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + new String(fname.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8) + ".xlsx");

            response.setContentType("application/msexcel");//定义输出类型
            int len;
            byte[] b = new byte[2048];
            while ((len = inputStream.read(b)) != -1) {
                os.write(b, 0, len);
            }
            response.setHeader("Content-Length", String.valueOf(inputStream.available()));

            inputStream.close();
            os.close();
        } catch (Exception e) {
            log.error(ExceptionUtils.getFullStackTrace(e));
        }
    }

    @Override
    public List<InvestmentDebtSummaryVO> summary(BaseInvestmentDebtDTO baseInvestmentDebtDTO) {
        if (StringUtil.isBlank(baseInvestmentDebtDTO.getFilingMonth())) {
            baseInvestmentDebtDTO.setFilingMonth(DateUtil.format(DateUtil.now(), DateUtil.PATTERN_MONTH));
        }
        List<PageData> unitList = orgzationService.getOneUnit(true).getList().stream()
                .filter(org -> !"0".equals(org.getString("parentId"))).collect(Collectors.toList());

        Map<String, String> unitMap = unitList.stream().collect(Collectors
                .toMap(org -> org.getString("id"), org -> org.getString("name"), (a, b) -> a));
        if (CollectionUtil.isEmpty(baseInvestmentDebtDTO.getOrgIds())) {
            List<String> orgIds = unitList.stream()
                    .map(org -> org.getString("id")).collect(Collectors.toList());
            baseInvestmentDebtDTO.setOrgIds(orgIds);
        }

        List<InvestmentDebtSummaryVO> dataList = baseMapper.summary(baseInvestmentDebtDTO);
        InvestmentDebtSummaryVO total = InvestmentDebtSummaryVO.builder().orgName("合计")
                .oneNumber(0).twoNumber(0).threeNumber(0).projectTotal(0).presentationCondition(StringPool.DASH).build();
        List<InvestmentDebtSummaryVO> results = new ArrayList<>();
        results.add(total);
        results.addAll(summary(unitMap, baseInvestmentDebtDTO.getOrgIds(), dataList, 2, "政府性项目小计", "一、", total));
        results.addAll(summary(unitMap, baseInvestmentDebtDTO.getOrgIds(), dataList, 1, "自营项目小计", "二、", total));
        return results;
    }

//    @Override TODO DEL
//    public String summaryExport(BaseInvestmentDebtDTO baseInvestmentDebtDTO) {
//        List<InvestmentDebtSummaryVO> results = summary(baseInvestmentDebtDTO);
//        String key = System.currentTimeMillis() + StringPool.DASH + UUID.randomUUID().toString().replace(StringPool.DASH, "");
//        String fileName = key + ".xlsx";
//        String exportPath = environment.getProperty("excel.path");
//        log.info("BaseInvestmentDebtServiceImpl exportPath--->" + exportPath);
//        /**
//         * 导出路径不存在则创建
//         */
//        File file = new File(exportPath);
//        if (!file.exists()) {
//            file.mkdirs();
//        }
//        InputStream inputStream = this.getClass().getResourceAsStream("/exceldemo/baseInvestmentDebtSummary.xlsx");
//        ExcelWriter excelWriter = EasyExcel.write(exportPath + fileName).withTemplate(inputStream).build();
//        FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
//        WriteSheet writeSheet = EasyExcel.writerSheet(0).build();
//        excelWriter.fill(results, fillConfig, writeSheet);
//
//        Map<String, Object> monthMap = new HashMap<>(16);
//        int month = Integer.valueOf(baseInvestmentDebtDTO.getFilingMonth().split(StringPool.DASH)[1]);
//        monthMap.put("month", month);
//        String excelName = month + "月份国有企业投资项目债务余额及结构汇总表";
//        redisUtils.set(key, excelName, 10 * 60);
//        excelWriter.fill(monthMap, writeSheet);
//        excelWriter.finish();
//        return key;
//    }

    private List<InvestmentDebtSummaryVO> summary(Map<String, String> unitMap, List<String> orgIds,
                                                  List<InvestmentDebtSummaryVO> dataList, Integer type,
                                                  String totalName, String index, InvestmentDebtSummaryVO total) {
        List<InvestmentDebtSummaryVO> results = new ArrayList<>();
        InvestmentDebtSummaryVO typeTotal = InvestmentDebtSummaryVO.builder().orgName(totalName).index(index)
                .oneNumber(0).twoNumber(0).threeNumber(0).projectTotal(0).presentationCondition(StringPool.DASH).build();
        results.add(typeTotal);
        int count = 1;
        for (String orgId : orgIds) {
            boolean flag = true;
            InvestmentDebtSummaryVO result = null;
            for (InvestmentDebtSummaryVO data : dataList) {
                if (unitMap.containsKey(orgId) &&
                        type.equals(data.getProjectCategory()) && orgId.equals(data.getOrgId())) {
                    result = data;
                    flag = false;
                    break;
                }
            }

            if (flag && unitMap.containsKey(orgId)) {
                result = InvestmentDebtSummaryVO.builder().orgName(unitMap.get(orgId)).build();
            }

            if (result != null) {
                result.setIndex(String.valueOf(count));
                count += 1;
                results.add(result);
                sum(typeTotal, result);
            }
        }

        sum(total, typeTotal);
        return results;
    }

    private void sum(InvestmentDebtSummaryVO total, InvestmentDebtSummaryVO result) {
        total.setOneNumber(BigDecimalUtil.integerAdd(total.getOneNumber(), result.getOneNumber()));
        total.setTwoNumber(BigDecimalUtil.integerAdd(total.getTwoNumber(), result.getTwoNumber()));
        total.setThreeNumber(BigDecimalUtil.integerAdd(total.getThreeNumber(), result.getThreeNumber()));
        total.setProjectTotal(BigDecimalUtil.integerAdd(total.getProjectTotal(), result.getProjectTotal()));
        total.setPlanTotalInvestment(BigDecimalUtil.add(total.getPlanTotalInvestment(), result.getPlanTotalInvestment()));
        total.setFiscalFunds(BigDecimalUtil.add(total.getFiscalFunds(), result.getFiscalFunds()));
        total.setShareholderCapital(BigDecimalUtil.add(total.getShareholderCapital(), result.getShareholderCapital()));
        total.setProjectLoan(BigDecimalUtil.add(total.getProjectLoan(), result.getProjectLoan()));
        total.setActualFinancialExpenditure(BigDecimalUtil.add(total.getActualFinancialExpenditure(), result.getActualFinancialExpenditure()));
        total.setActualFiscalFunds(BigDecimalUtil.add(total.getActualFiscalFunds(), result.getActualFiscalFunds()));
        total.setActualShareholderCapital(BigDecimalUtil.add(total.getActualShareholderCapital(), result.getActualShareholderCapital()));
        total.setDebtCapitalTotal(BigDecimalUtil.add(total.getDebtCapitalTotal(), result.getDebtCapitalTotal()));
        total.setDebtCapitalLoan(BigDecimalUtil.add(total.getDebtCapitalLoan(), result.getDebtCapitalLoan()));
        total.setDebtCapitalShareholderAdvance(BigDecimalUtil.add(total.getDebtCapitalShareholderAdvance(), result.getDebtCapitalShareholderAdvance()));
        total.setFutureRaiseDebtAmount(BigDecimalUtil.add(total.getFutureRaiseDebtAmount(), result.getFutureRaiseDebtAmount()));
    }

//    @Override
//    @Async("ttlExecutor")
//    public Future<ImportResult> importExcel(String progressId, InputStream inputStream) {
//        String progress = "progress";
//        String key = progressId + "#half:hour";
//        try {
//            byte[] bytes = IOUtils.toByteArray(inputStream);
//            inputStream = new ByteArrayInputStream(bytes);
//
//            Map<String, Map<String, String>> mapRef = getRef();
//            Map<String, InvestmentDebtInfo> projectMap = getProjectMap();
//
//            List<Object> baseList = new ArrayList<>();
//            EasyExcel.read(inputStream).build()
//                    .read(EasyExcel.readSheet(0).headRowNumber(1).head(BaseInvestmentDebtImportExcelBean.class)
//                            .registerReadListener(new PageReadListener<>(list -> baseList.addAll(list))).build());
//
//            ImportExcelUtil.filterEmpty(baseList);
//            ImportResult baseResult = checkBaseData(mapRef, baseList);
//            if (!baseResult.isSuccess()) {
//                CacheUtil.put(progress, progress, key, baseResult.getMsg());
//                return new AsyncResult<>(baseResult);
//            }
//
//            inputStream.reset();
//            List<Object> investmentList = new ArrayList<>();
//            EasyExcel.read(inputStream).build()
//                    .read(EasyExcel.readSheet(1).headRowNumber(6).head(InvestmentDebtImportExcelBean.class)
//                            .registerReadListener(new PageReadListener<>(list -> investmentList.addAll(list))).build());
//            ImportExcelUtil.filterEmpty(investmentList);
//            ImportResult investmentResult = checkInvestData(mapRef, projectMap, investmentList, progressId);
//            if (!investmentResult.isSuccess()) {
//                CacheUtil.put(progress, progress, key, investmentResult.getMsg());
//                return new AsyncResult<>(investmentResult);
//            }
//
//            // 主表信息
//            BaseInvestmentDebt baseInvestmentDebt = (BaseInvestmentDebt) ImportExcelUtil.getEntityByExcelBean((BaseInvestmentDebtImportExcelBean) baseList.get(0), new BaseInvestmentDebt());
//            baseInvestmentDebt.setFilingMonth(baseInvestmentDebt.getFilingMonth().trim());
//            BaseInvestmentDebt old = getOldData(baseInvestmentDebt);
//            if (Optional.ofNullable(old).isPresent()) {
//                //如果有老数据 则删除子表旧数据
//                baseInvestmentDebt.setId(old.getId());
//                investmentDebtService.deleteByBaseId(old.getId());
//            } else {
//                baseInvestmentDebt.setType(1);
//                saveOrUpdate(baseInvestmentDebt);
//            }
//
//            String fillingUnitId = baseInvestmentDebt.getFilingUnitId();
//            String fillingMonth = baseInvestmentDebt.getFilingMonth();
//            List<String> childIds = getChildIds(fillingUnitId);
//            if (CollectionUtil.isNotEmpty(childIds)) {
//                BaseInvestmentDebt twoOldBase = getOne(new LambdaQueryWrapper<BaseInvestmentDebt>()
//                        .eq(BaseInvestmentDebt::getFilingMonth, fillingMonth)
//                        .eq(BaseInvestmentDebt::getFilingUnitId, fillingUnitId)
//                        .eq(BaseInvestmentDebt::getType, 2));
//                if (!Optional.ofNullable(twoOldBase).isPresent()) {
//                    // 该企业有下级 创建合计数据
//                    BaseInvestmentDebt twoBase = BaseInvestmentDebt.builder().filingMonth(fillingMonth).filingUnitId(fillingUnitId).type(2).build();
//                    this.saveOrUpdate(twoBase);
//                }
//            }
//
//            int count = 0;
//            int size = investmentList.size();
//            // 国有企业投资项目债务余额及结构情况表
//            for (Object readExcel : investmentList) {
//                InvestmentDebt investmentDebt = (InvestmentDebt) ImportExcelUtil.getEntityByExcelBean((InvestmentDebtImportExcelBean) readExcel, new InvestmentDebt());
//                //入库
//                try {
//                    investmentDebt.setBaseInvestmentDebtId(baseInvestmentDebt.getId());
//                    investmentDebtService.saveOrUpdate(investmentDebt);
//                    ArrayList<Long> ids = new ArrayList<>();
//                    ids.add(baseInvestmentDebt.getId());
////					List<InvestmentDebtVO> investmentDebtVOS = investmentDebtMapper.summaryByBaseIds(ids);
////					if (null!=investmentDebtVOS&&investmentDebtVOS.size()>0){
////						baseInvestmentDebt.setSummaryList(investmentDebtVOS);
////						this.saveOrUpdate(baseInvestmentDebt);
////					}
//                    baseInvestmentDebt.setSummaryList(new ArrayList<>());
//                    this.saveOrUpdate(baseInvestmentDebt);
//                    count++;
//                    int value = count * 100 / size;
//                    CacheUtil.put(progress, progress, key, value + 100);
//                } catch (Exception e) {
//                    log.error(investmentDebt + "导入失败");
//                    CacheUtil.put(progress, progress, key, investmentDebt + "导入失败");
//                    return new AsyncResult<>(new ImportResult(false, investmentDebt + "导入失败"));
//                }
//            }
//
//        } catch (Exception e) {
//            log.error(ExceptionUtils.getFullStackTrace(e));
//            log.error("解析失败");
//            CacheUtil.put(progress, progress, key, "解析失败");
//            return new AsyncResult<>(new ImportResult(false, "解析失败"));
//        }
//
//        CacheUtil.put(progress, progress, key, "导入成功");
//        return new AsyncResult<>(new ImportResult(true, "导入成功"));
//    }


    /**
     * 递归 树的初始化
     *
     * @param orgList
     * @param oneMap
     * @param twoMap
     * @return
     */
    private List<InvestmentDebtTreeVO> setTree(List<PageData> orgList, Map<String, List<BaseInvestmentDebt>> oneMap, Map<String, List<BaseInvestmentDebt>> twoMap) {
        List<InvestmentDebtTreeVO> tree = new ArrayList<>();
        for (PageData org : orgList) {
            List<PageData> orgChildren = (List<PageData>) org.get("children");
            String fillingUnitId = (String) org.get("id");
            String fillingUnitName = (String) org.get("name");
            String orgCode = (String) org.get("orgCode");
            String orgType = org.getString("type");
            BaseInvestmentDebt oneBase = new BaseInvestmentDebt();
            boolean flag = false;
            if (oneMap.containsKey(fillingUnitId)) {
                flag = true;
                oneBase = oneMap.get(fillingUnitId).get(0);
            }
            if (CollectionUtil.isNotEmpty(orgChildren)) {
                InvestmentDebtTreeVO result = InvestmentDebtTreeVO.builder().fillingUnitId(fillingUnitId)
                        .status(FormStatusConstant.NOFILLING)
                        .fillingUnitName(fillingUnitName).type(3).build();
                List<InvestmentDebtTreeVO> children = new ArrayList<>();
                //判断该单位是否为集团和下级
                if (StringUtil.isNotBlank(orgCode) && "2".equals(orgType)) {
                    result.setType(2);
                    result.setTypeName("集团合并表");
                    //自己节点为合计表
                    if (twoMap.containsKey(fillingUnitId)) {
                        BaseInvestmentDebt twoBase = twoMap.get(fillingUnitId).get(0);
                        result.setStatus(twoBase.getStatus());
                        result.setFillingMonth(twoBase.getFilingMonth());
                        result.setFormType(String.valueOf(FormTypeConstant.IM_BASE_INVESTMENT_DEBT_FORM));
                        result.setBaseInvestmentDebtId(twoBase.getId());
                    }

                    if (flag) {
                        //子节点第一个为 单表
                        InvestmentDebtTreeVO child = InvestmentDebtTreeVO.builder().fillingUnitId(fillingUnitId).fillingUnitName(fillingUnitName)
                                .fillingMonth(oneBase.getFilingMonth()).baseInvestmentDebtId(oneBase.getId()).status(oneBase.getStatus())
                                .formType(String.valueOf(FormTypeConstant.IM_BASE_INVESTMENT_DEBT_FORM)).typeName("单户表").type(1)
                                .build();
                        children.add(child);
                    }
                }
                children.addAll(setTree(orgChildren, oneMap, twoMap));
                result.setChildren(children);
                if (CollectionUtil.isNotEmpty(children) || twoMap.containsKey(fillingUnitId)) {
                    tree.add(result);
                }
            } else {
                if (flag) {
                    //自己节点为 单表
                    InvestmentDebtTreeVO result = InvestmentDebtTreeVO.builder().fillingUnitId(fillingUnitId).fillingUnitName(fillingUnitName)
                            .fillingMonth(oneBase.getFilingMonth()).typeName("单户表")
                            .formType(String.valueOf(FormTypeConstant.IM_BASE_INVESTMENT_DEBT_FORM))
                            .baseInvestmentDebtId(oneBase.getId()).type(1).status(oneBase.getStatus())
                            .build();
                    tree.add(result);
                }
            }
        }
        return tree;
    }

    /**
     * 获取子企业id
     *
     * @param fillingUnitId
     * @return
     */
    private List<String> getChildIds(String fillingUnitId) {
        List<String> fillingUnitIds = new ArrayList<>();
        try {
            List<PageData> children = orgzationService.getChlidList(fillingUnitId);
            if (CollectionUtil.isNotEmpty(children)) {
                for (PageData child : children) {
                    if (!fillingUnitId.equals(child.get("id"))) {
                        fillingUnitIds.add((String) child.get("id"));
                    }
                }
            }
        } catch (Exception e) {
            log.error(ExceptionUtils.getFullStackTrace(e));
        }
        return fillingUnitIds;
    }

    /**
     * 是否为父节点
     *
     * @param fillingUintId
     * @return
     */
    private boolean isParent(String fillingUintId) {
        try {
            List<PageData> children = orgzationService.getChlidList(fillingUintId);

            if (CollectionUtil.isNotEmpty(children)) {
                return children.size() != 1 || !fillingUintId.equals(children.get(0).get("id"));
            } else {
                return false;
            }
        } catch (Exception e) {
            log.error(ExceptionUtils.getFullStackTrace(e));
            return false;
        }
    }

    private Map<String, Map<String, String>> getRef() {
        Map<String, Map<String, String>> mapRefs = new HashMap<>(16);
//		mapRefs.put("projectNatureRef",baseInfoService.getChildMap(ValueSetConstant.PROJECT_NATURE));
//		mapRefs.put("enterpriseRankRef",baseInfoService.getChildMap(ValueSetConstant.ENTERPRISE_RANK));
        HashMap<String, String> statusMap = new HashMap<>();
        HashMap<String, String> categoryMap = new HashMap<>();
        statusMap.put("1", "筹建");
        statusMap.put("2", "在建");
        statusMap.put("3", "建成");
        categoryMap.put("1", "自营项目");
        categoryMap.put("2", "政府性项目");
        mapRefs.put("status", statusMap);
        mapRefs.put("category", categoryMap);
        Map<String, String> unitRef = new HashMap<>(512);
        Map<String, String> propertyRef = new HashMap<>(2048);
        try {
            List<PageData> allOrgs = orgzationDao.list(null);
            if (CollectionUtil.isNotEmpty(allOrgs)) {
                for (PageData pageData : allOrgs) {
                    unitRef.put((String) pageData.get("name"), (String) pageData.get("id"));
                }

            }
            List<PageData> allProperty = propertyBasicsDao.list(null);
            if (CollectionUtil.isNotEmpty(allProperty)) {
                for (PageData property : allProperty) {
                    propertyRef.put((String) property.get("orgName"), (String) property.get("id"));
                }
            }
        } catch (Exception e) {
            log.error(ExceptionUtils.getFullStackTrace(e));
        }
        mapRefs.put("unitRef", unitRef);
        mapRefs.put("propertyRef", propertyRef);

        return mapRefs;
    }

//    private Map<String, InvestmentDebtInfo> getProjectMap() { TODO DEL
//        List<InvestmentDebtInfo> investmentDebtInfos = investmentDebtInfoService.list(new QueryWrapper<InvestmentDebtInfo>().eq("create_company_id", TokenUtil.getTokenOrgId()));
//        Map<String, InvestmentDebtInfo> map = new HashMap<>();
//        if (CollectionUtil.isNotEmpty(investmentDebtInfos)) {
//            map = investmentDebtInfos.stream().collect(Collectors.toMap(InvestmentDebtInfo::getProjectName, a -> a, (k1, k2) -> k1));
//        }
//        return map;
//    }

    private ImportResult checkBaseData(Map<String, Map<String, String>> mapRef, List<Object> readExcels) {
        ImportResult importResult = new ImportResult(true, "");

        StringBuilder msg = new StringBuilder();

        if (CollectionUtil.isNotEmpty(readExcels)) {
            int index = 2;
            BaseInvestmentDebtImportExcelBean excelBean = (BaseInvestmentDebtImportExcelBean) readExcels.get(0);

            //判空
            msg.append(ImportExcelUtil.checkEmpty("1", "填报单位",
                    excelBean.getFilingUnitId(), index).getMsg());
            //判空
            msg.append(ImportExcelUtil.checkEmpty("1", "主管部门",
                    String.valueOf(excelBean.getDeptId()), index).getMsg());
            //判空
            msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_DATE_MONTH, "1", "填报年月",
                    excelBean.getFilingMonth(), index).getMsg());
            //判断完类型若有错直接返回
            if (msg.toString().length() > 0) {
                return new ImportResult(false, msg.toString());
            }

            //对象和字典是否存在校验
            //单位名称
            excelBean.setFilingUnitId(StringUtil.cleanChars(excelBean.getFilingUnitId()));
            if (mapRef.get("unitRef").containsKey(excelBean.getFilingUnitId())) {
                String companyName = excelBean.getFilingUnitId();
                excelBean.setFilingUnitId(mapRef.get("unitRef").get(excelBean.getFilingUnitId()));
                if (!TokenUtil.getTokenOrgId().equals(excelBean.getFilingUnitId())) {
                    msg.append("sheet1第" + index + "行(填报单位=" + companyName + ")不是当前登录单位\n");
                }
            } else if (!StringUtil.isEmpty(excelBean.getFilingUnitId())) {
                msg.append("sheet1第" + index + "行(填报单位=" + excelBean.getFilingUnitId() + ")在系统中不存在\n");
            }

            if (mapRef.get("unitRef").containsKey(excelBean.getDeptId())) {
                excelBean.setDeptId(mapRef.get("unitRef").get(excelBean.getDeptId()));
            } else if (!StringUtil.isEmpty(excelBean.getFilingUnitId())) {
                msg.append("sheet1第" + index + "行(主管部门=" + excelBean.getDeptId() + ")在系统中不存在\n");
            }

            QueryWrapper<BaseInvestmentDebt> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("filing_unit_id", excelBean.getFilingUnitId());
            queryWrapper.eq("filing_month", excelBean.getFilingMonth());
            queryWrapper.ne("status", FormStatusConstant.UNREVIEWED);
            if (Optional.ofNullable(getOne(queryWrapper)).isPresent()) {
                msg.append("sheet1该月度数据已上报\n");
            }

        } else {
            msg.append("sheet1填报单位和填报单位未填写\n");
        }

        //统一放置报错
        if (msg.toString().length() > 0) {
            importResult = new ImportResult(false, msg.toString());
        }
        return importResult;

    }

//    private ImportResult checkInvestData(Map<String, Map<String, String>> mapRef, Map<String, InvestmentDebtInfo> investmentDebtInfoMap, List<Object> readExcels, String progressId) { TODO DEL
//
//        ImportResult importResult = new ImportResult(true, "");
//
//        StringBuilder msg = new StringBuilder();
//        for (Object readExcel : readExcels) {
//            InvestmentDebtImportExcelBean excelBean = (InvestmentDebtImportExcelBean) readExcel;
//            int index = readExcels.indexOf(readExcel);
//
//            //判空
//            msg.append(ImportExcelUtil.checkEmpty("2", "债务项目名称",
//                    excelBean.getProjectName(), index).getMsg());
//            msg.append(ImportExcelUtil.checkEmpty("2", "项目公司",
//                    excelBean.getProjectCompanyId(), index).getMsg());
//
//            //判空
//            String isFundInvestment = excelBean.getIsFundInvestment();
//            if (org.apache.commons.lang.StringUtils.isEmpty(isFundInvestment)) {
//                msg.append(ImportExcelUtil.checkEmpty("2", "是否基金投资",
//                        excelBean.getIsFundInvestment(), index).getMsg());
//            } else if ("1".equals(isFundInvestment)) {
//                //判空
//                msg.append(ImportExcelUtil.checkEmpty("2", "项目投资建设状况",
//                        excelBean.getConstructionStatus(), index).getMsg());
//            } else if ("2".equals(isFundInvestment)) {
//                //不填
//                msg.append(ImportExcelUtil.checkNull("2", "项目投资建设状况",
//                        excelBean.getConstructionStatus(), index).getMsg());
//            } else {
//                //是否基金投资
//                msg.append("sheet2第" + index + "行(是否基金投资=" + excelBean.getIsFundInvestment() + ")在系统中不存在\n");
//            }
//
//            //判断类型
//            msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_INTEGER, "2", "是否基金投资",
//                    excelBean.getIsFundInvestment(), index).getMsg());
//            msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_BIGDECIMAL, "2", "计划总投资（调整后）",
//                    excelBean.getPlanTotalInvestment(), index).getMsg());
//            msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_BIGDECIMAL, "2", "财政性资金",
//                    excelBean.getFiscalFunds(), index).getMsg());
//            msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_BIGDECIMAL, "2", "股东资本金",
//                    excelBean.getShareholderCapital(), index).getMsg());
//            msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_BIGDECIMAL, "2", "项目借款",
//                    excelBean.getProjectLoan(), index).getMsg());
//            msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_BIGDECIMAL, "2", "建成项目竣工决算数",
//                    excelBean.getCompletedProjectsAccounts(), index).getMsg());
//            msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_BIGDECIMAL, "2", "项目实际财务支出",
//                    excelBean.getActualFinancialExpenditure(), index).getMsg());
//            msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_BIGDECIMAL, "2", "财政性资金",
//                    excelBean.getActualFiscalFunds(), index).getMsg());
//            msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_BIGDECIMAL, "2", "股东资本金",
//                    excelBean.getActualShareholderCapital(), index).getMsg());
//            msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_BIGDECIMAL, "2", "合计",
//                    excelBean.getDebtCapitalTotal(), index).getMsg());
//            msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_BIGDECIMAL, "2", "项目借款",
//                    excelBean.getDebtCapitalLoan(), index).getMsg());
//            msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_BIGDECIMAL, "2", "股东垫付资本金",
//                    excelBean.getDebtCapitalShareholderAdvance(), index).getMsg());
//            msg.append(ImportExcelUtil.checkType(ImportExcelUtil.TYPE_BIGDECIMAL, "2", "未来还需筹集的债务金额",
//                    excelBean.getFutureRaiseDebtAmount(), index).getMsg());
//        }
//        //判断完类型若有错直接返回
//        if (msg.toString().length() > 0) {
//            return new ImportResult(false, msg.toString());
//        }
//
//        //对象和字典是否存在校验
//        int size = readExcels.size();
//        int count = 0;
//        for (Object readExcel : readExcels) {
//            InvestmentDebtImportExcelBean excelBean = (InvestmentDebtImportExcelBean) readExcel;
//            int index = readExcels.indexOf(readExcel);
//
//            //项目投资建设状况
//            if (StringUtil.isNotBlank(excelBean.getConstructionStatus())) {
//                if (!mapRef.get("status").containsKey(excelBean.getConstructionStatus())) {
//                    msg.append("sheet2第" + index + "行(项目投资建设状况=" + excelBean.getConstructionStatus() + ")在系统中不存在\n");
//                }
//            }
//
//            //判断项目名称，回传项目id，项目类型
//            if (investmentDebtInfoMap.containsKey(excelBean.getProjectName())) {
//                excelBean.setProjectId(String.valueOf(investmentDebtInfoMap.get(excelBean.getProjectName()).getId()));
//                excelBean.setProjectCategory(String.valueOf(investmentDebtInfoMap.get(excelBean.getProjectName()).getProjectCategory()));
//            } else {
//                msg.append("sheet2第" + index + "行(项目名称=" + excelBean.getProjectName() + ")在系统中不存在\n");
//            }
////			if(mapRef.get("propertyRef").containsKey(excelBean.getProjectName())){
////				excelBean.setProjectName(mapRef.get("propertyRef").get(excelBean.getProjectName()));
////			}else if(!StringUtil.isEmpty(excelBean.getProjectName())){
////				msg.append("sheet2第" + index + "行(项目名称=" + excelBean.getProjectName() + ")在系统中不存在\n");
////			}
//
//            if (mapRef.get("propertyRef").containsKey(excelBean.getProjectCompanyId())) {
//                excelBean.setProjectCompanyId(mapRef.get("propertyRef").get(excelBean.getProjectCompanyId()));
//            } else if (!StringUtil.isEmpty(excelBean.getProjectCompanyId())) {
//                msg.append("sheet2第" + index + "行(项目公司=" + excelBean.getProjectCompanyId() + ")在系统中不存在\n");
//            }
//
//            count++;
//            int value = count * 100 / size;
//            CacheUtil.put("progress", "progress", progressId, value);
//        }
//
//        //统一放置报错
//        if (msg.toString().length() > 0) {
//            importResult = new ImportResult(false, msg.toString());
//        }
//        return importResult;
//    }

    private BaseInvestmentDebt getOldData(BaseInvestmentDebt baseInvestmentDebt) {
        LambdaQueryWrapper<BaseInvestmentDebt> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BaseInvestmentDebt::getFilingUnitId, baseInvestmentDebt.getFilingUnitId());
        queryWrapper.eq(BaseInvestmentDebt::getFilingMonth, baseInvestmentDebt.getFilingMonth());
//		queryWrapper.eq("dept_id", baseInvestmentDebt.getDeptId());
        queryWrapper.eq(BaseInvestmentDebt::getType, 1);
        return getOne(queryWrapper);
    }


//    /** TODO DEL
//     * 处理项目信息
//     *
//     * @param baseInvestmentDebts
//     * @return
//     */
//    private List<BaseInvestmentDebt> doProcessProjectInfo(List<BaseInvestmentDebt> baseInvestmentDebts) {
//
//
//        List<InvestmentDebtInfo> allInvestmentDebtInfoList = investmentDebtInfoService.list(new LambdaQueryWrapper<InvestmentDebtInfo>()
//                .in(InvestmentDebtInfo::getDataSource, "3"));
//
//        for (BaseInvestmentDebt baseInvestmentDebt : baseInvestmentDebts) {
//            //详细
//            List<InvestmentDebt> investmentDebts = baseInvestmentDebt.getInvestmentDebts();
//
//            if (CollectionUtil.isNotEmpty(investmentDebts)) {
////                List<InvestmentDebtInfo> investmentDebtInfoList = investmentDebtInfoService.list(new LambdaQueryWrapper<InvestmentDebtInfo>()
////                        .in(InvestmentDebtInfo::getDataSourceId, investmentDebts.stream().map(InvestmentDebt::getProjectId).collect(Collectors.toList())));
//
//
//                investmentDebts.forEach(item -> {
//                    Optional<InvestmentDebtInfo> investmentDebtInfoOptional = allInvestmentDebtInfoList.stream().filter(e -> e.getDataSourceId().equals(item.getProjectId().toString())).findFirst();
//                    if (investmentDebtInfoOptional.isPresent()) {
//                        InvestmentDebtInfo investmentDebtInfo = investmentDebtInfoOptional.get();
//                        item.setProjectId(investmentDebtInfo.getId());
//                        item.setProjectName(investmentDebtInfo.getProjectName());
//                        item.setProjectCategory(investmentDebtInfo.getProjectCategory());
//                        item.setProjectCompanyId(investmentDebtInfo.getProjectCompanyId());
//                        item.setIsFundInvestment(investmentDebtInfo.getIsFundInvestment());
//                        item.setConstructionStatus(investmentDebtInfo.getConstructionStatus());
//                        item.setBalancedPlanning(investmentDebtInfo.getBalancedPlanning());
//                        item.setPlanTotalInvestment(investmentDebtInfo.getPlanTotalInvestment());
//                        //资金
//                        BigDecimal fiscalFunds = investmentDebtInfo.getFiscalFunds() == null ? new BigDecimal(0) : investmentDebtInfo.getFiscalFunds();
//                        BigDecimal shareholderCapital = investmentDebtInfo.getShareholderCapital() == null ? new BigDecimal(0) : investmentDebtInfo.getShareholderCapital();
//                        BigDecimal projectLoan = investmentDebtInfo.getProjectLoan() == null ? new BigDecimal(0) : investmentDebtInfo.getProjectLoan();
//
//                        item.setFiscalFunds(fiscalFunds);
//                        item.setShareholderCapital(shareholderCapital);
//                        item.setProjectLoan(projectLoan);
//                        item.setPlanTotalInvestmentSum(fiscalFunds.add(shareholderCapital).add(projectLoan));
//                    }
//                });
//
//            }
//
//        }
//        return baseInvestmentDebts;
//    }
}
